﻿#ifndef KAT_SINGLETON_H
#define KAT_SINGLETON_H

#include "Singleton.h"
#include "kat.h"
#include <boost/cstdint.hpp>
#include <boost/noncopyable.hpp>

namespace kat {
  template <typename T>
  class Singleton : boost::noncopyable {
  public:
    virtual ~Singleton(void) {
      m_pSingleton = NULL;
    }

    static T* getInstancePtr(void) {
      if (m_pSingleton == NULL)
        static T singleton;
      return m_pSingleton;
    }
    static T& getInstance(void) {return (*getInstancePtr());}

  protected:
    Singleton(void) {
      if (m_pSingleton)
        throw Kat_Exception();
      boost::int32_t offset =
        (boost::int32_t)(T*)1 - (boost::int32_t)(Singleton<T>*)(T*)1;
      m_pSingleton = (T*)((boost::int32_t)this + offset);
    }

    static T* m_pSingleton;
  };
}

template <typename T> T* kat::Singleton<T>::m_pSingleton = NULL;

#endif
